package com.zmn.oms.business.impl.base;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.constant.TagConsts;
import com.zmn.base.common.data.common.dio.tags.TagsCheckDIO;
import com.zmn.base.common.data.common.dro.tags.TagsDRO;
import com.zmn.base.common.data.common.query.tags.TagsQuery;
import com.zmn.base.common.data.dubbo.interfaces.tags.TagsListRemoteService;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.ec.DefaultEcProductQuery;
import com.zmn.base.product.common.dto.product.ec.ProductBaseDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductForeignListRemoteService;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.entity.advancequote.AdvanceQuoteOpenQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 类描述：
 *
 * @author liuying
 * @date 2019/01/24 17:46
 */
@Slf4j
@Service
public class BaseCodeServiceImpl implements BaseCodeService {

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    TagsListRemoteService tagsListRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected ProductForeignListRemoteService productForeignListRemoteService;

    @Override
    public boolean isChannelOrderSyncTo58(Integer channelId) {
        TagsDRO tagsDRO = this.getOneBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, TagConsts.TAG_ONE_TYPE_OMS_CHANNEL_SYNC_TO_58, null);
        if (tagsDRO == null || StringUtils.isBlank(tagsDRO.getName())) {
            return false;
        }
        return this.contains(tagsDRO.getName(), channelId);
    }

    @Override
    public Integer getChannelInputType(Integer plat, Integer channelId, Integer defaultInputType) {
        if (defaultInputType != null && !Objects.equals(OrderConsts.ORDER_INPUT_TYPE_MANUAL, defaultInputType)) {
            return defaultInputType;
        }
        TagsDRO tagsDRO = this.getOneBaseCodeMap(plat, TagConsts.TAG_ONE_TYPE_OMS_CHANNEL_INPUT_TYPE, channelId);
        if (tagsDRO == null) {
            return OrderConsts.ORDER_INPUT_TYPE_MANUAL;
        }
        return Optional.ofNullable(tagsDRO.getThreeTypeId()).orElse(OrderConsts.ORDER_INPUT_TYPE_MANUAL);
    }

    @Override
    public Integer getChannelId(Integer plat, Integer channelBaseCodeId) throws OmsBaseException {
        TagsDRO tagsDRO = this.getOneBaseCodeMap(plat, TagConsts.TAG_ONE_TYPE_OMS_CHANNEL_TYPE, channelBaseCodeId);
        if (tagsDRO == null) {
            throw new OmsBaseException("请配置默认渠道");
        }
        return Integer.parseInt(tagsDRO.getName().trim());
    }

    /**
     * 城市 是否需要完成码
     */
    @Override
    public boolean needSecurityCode(Integer plat, Integer cityId, Integer agent) {
        TagsCheckDIO tagsCheckDIO = TagsCheckDIO.builder().oneTypeId(TagConsts.TAG_ONE_TYPE_NEED_SECURITY_CODE).twoTypeId(cityId).name(agent + "").plat(plat).build();
        ResponseDTO<Boolean> remoteRespDTO = tagsListRemoteService.checkByTagsCheckDIO(tagsCheckDIO);
        if (remoteRespDTO.isSuccess() && remoteRespDTO.getData()) {
            return true;
        }
        return false;
    }

    @Override
    public boolean needVisitCode(Integer cityId) {
        TagsDRO tagsDRO = getOneBaseCodeMap(0, TagConsts.TAG_ONE_TYPE_STANDARD_PRICE_CODE_CITY_CHANNEL_BLACKLIST, cityId);
        if (tagsDRO != null) {
            return true;
        }

        return false;
    }

    @Override
    public Integer getStandardPrice(Integer plat, Integer cityId, Integer channelId) {

        // 城市黑名单
        TagsQuery cityBlackListTagsDIO = new TagsQuery();
        cityBlackListTagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        cityBlackListTagsDIO.setOneTypeId(TagConsts.TAG_ONE_TYPE_STANDARD_PRICE_CODE_CITY_BLACKLIST);
        ResponseDTO<List<TagsDRO>> cityBackListResponseDTO = tagsListRemoteService.listByQuery(cityBlackListTagsDIO);
        if (CollectionUtils.isNotEmpty(cityBackListResponseDTO.getData())) {
            if (this.contains(cityBackListResponseDTO.getData().get(0).getName(), cityId)) {
                return GlobalConsts.NO;
            }
        }

        // 渠道黑名单
        TagsQuery channelBackListTagsDIO = new TagsQuery();
        channelBackListTagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        channelBackListTagsDIO.setOneTypeId(TagConsts.TAG_ONE_TYPE_STANDARD_PRICE_CODE_CHANNEL_BLACKLIST);
        ResponseDTO<List<TagsDRO>> channelBackListResponseDTO = tagsListRemoteService.listByQuery(channelBackListTagsDIO);
        if (CollectionUtils.isNotEmpty(channelBackListResponseDTO.getData())) {
            if (this.contains(channelBackListResponseDTO.getData().get(0).getName(), channelId)) {
                return GlobalConsts.NO;
            }
        }

        // 开通城市的渠道黑名单
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        tagsDIO.setOneTypeId(TagConsts.TAG_ONE_TYPE_STANDARD_PRICE_CODE_CITY_CHANNEL_BLACKLIST);
        tagsDIO.setTwoTypeId(cityId);
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            // 使用黑名单机制
            TagsDRO tagsDRO = responseDTO.getData().get(0);
            if (StringUtils.isBlank(tagsDRO.getName())) {
                return GlobalConsts.YES;
            }
            String channelIds = String.format(",%s,", tagsDRO.getName());
            String channelIdStr = String.format(",%s,", channelId);
            if (channelIds.contains(channelIdStr)) {
                return GlobalConsts.NO;
            } else {
                return GlobalConsts.YES;
            }
        }
        return GlobalConsts.NO;
    }

    private boolean contains(String source, Integer value) {
        String source1 = String.format(",%s,", source);
        String str = String.format(",%s,", value);
        return source1.contains(str);
    }

    @Override
    public String getDistributeWeight(Integer plat, Integer cityId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        tagsDIO.setOneTypeId(TagConsts.TAG_ONE_TYPE_DISTRIBUTE_WEIGHT);
        tagsDIO.setTwoTypeId(cityId);
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            // 距离,手头单,当日成功单,技能评分
            TagsDRO tagsDRO = responseDTO.getData().get(0);
            String weightStr = tagsDRO.getName();
            boolean isWeight = StringUtils.isBlank(weightStr) || weightStr.split(",").length != 4;
            if (isWeight) {
                weightStr = this.getDistributeWeight(plat, 0);
            }
            return weightStr;
        }
        return null;
    }

    /**
     * 城市 是否强制定位
     */
    @Override
    public boolean forceLocation(Integer plat, Integer cityId) {
        TagsDRO tagsDRO = this.getOneBaseCodeMap(plat, TagConsts.TAG_ONE_TYPE_FORCE_LOCATION, cityId);
        if (tagsDRO != null) {
            return true;
        }
        return false;
    }

    /**
     * 城市是否支全家享会员
     */
    @Override
    public boolean supportSaleMember(Integer plat, Integer cityId) {
        return true;
//        ResponseDTO<BaseCodeMapDRO> remoteRespDTO = baseCodeMapRemoteService.queryByTypeAndName(GlobalConsts.BASE_CODE_MAP_ONE_TYPE_SUPPORT_MEMBER, cityId, null, plat);
//        if (remoteRespDTO.getStatusBool() && remoteRespDTO.getItems() != null && remoteRespDTO.getItems().size() > 0) {
//            return true;
//        }
//
//        return false;
    }

    /**
     * 全家享会员服务电话
     */
    @Override
    public String getMemberServicePhone(Integer plat) {
        TagsDRO oneBaseCodeMap = this.getOneBaseCodeMap(plat, TagConsts.TAG_ONE_TYPE_MEMBER_SERVICE_PHONE, GlobalConsts.NONE);
        if (!Objects.isNull(oneBaseCodeMap)) {
            return oneBaseCodeMap.getName();
        }

        return null;
    }

    /**
     * 会员单可以操作的距离,单位米
     */
    @Override
    public Integer getMemberOrderOperationDistance(Integer plat) {
        return 1000000000;
    }

    /**
     * 渠道是否发送短信
     */
    @Override
    public boolean needSendSms(Integer channelId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(GlobalConsts.NONE);
        tagsDIO.setOneTypeId(TagConsts.TAG_ONE_TYPE_DISABLE_SMS_CHANNEL);
        tagsDIO.setTwoTypeId(channelId);
        ResponseDTO<List<TagsDRO>> remoteRespDTO = tagsListRemoteService.listByQuery(tagsDIO);
        return !remoteRespDTO.isSuccess() || !CollectionUtil.isNotNullOrEmpty(remoteRespDTO.getData());
    }

    @Override
    public String getTmallServiceItemName(Integer productId) {
        TagsDRO tagsDRO = this.getOneBaseCodeMap(null, TagConsts.TAG_ONE_TYPE_OMS_TMALL_SERVICEITEM, productId);
        if (Objects.isNull(tagsDRO)) {
            return null;
        }
        return tagsDRO.getName();
    }

    /**
     * 查询列表
     * @param plat
     * @param oneTypeId
     * @param twoTypeId
     * @param threeTypeId
     * @return
     */
    @Override
    public List<KVDict<Integer>> getBaseCodeMap(Integer plat, Integer oneTypeId, Integer twoTypeId, Integer threeTypeId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(plat);
        tagsDIO.setOneTypeId(oneTypeId);
        tagsDIO.setTwoTypeId(twoTypeId);
        tagsDIO.setStatus(GlobalConsts.YES);
        log.info("获取公共配置入参：【{}】", JSON.toJSONString(tagsDIO));
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        log.info("获取公共配置出参：【{}】", JSON.toJSONString(responseDTO));

        List<KVDict<Integer>> typeList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(responseDTO.getData())) {
            List<TagsDRO> items = responseDTO.getData();
            items.forEach(tagsDRO -> typeList.add(KVDict.<Integer>builder().value(tagsDRO.getTagId()).text(tagsDRO.getName()).build()));
        }
        return typeList;
    }

    /**
     * 查询码表
     *
     * @param oneTypeId
     * @param twoTypeId
     * @return
     */
    @Override
    public List<KVDict<Integer>> getBaseCodeMap(Integer plat, Integer oneTypeId, Integer twoTypeId) {
        return getBaseCodeMap(plat, oneTypeId, twoTypeId, null);
    }

    /**
     * 查询码表
     *
     * @param oneTypeId
     * @return
     */
    @Override
    public List<KVDict<Integer>> getBaseCodeMap(Integer plat, Integer oneTypeId) {
        return getBaseCodeMap(plat, oneTypeId, null);
    }

    @Override
    public TagsDRO getOneBaseCodeMap(Integer plat, Integer oneTypeId, Integer twoTypeId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(plat);
        tagsDIO.setOneTypeId(oneTypeId);
        tagsDIO.setTwoTypeId(twoTypeId);
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            return responseDTO.getData().get(0);
        }
        return null;
    }

    @Override
    public Integer getOneTwoTypeId(Integer plat, Integer oneTypeId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(plat);
        tagsDIO.setOneTypeId(oneTypeId);
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            return responseDTO.getData().get(0).getTwoTypeId();
        }
        return null;
    }

    /**
     *
     * @param plat
     * @param oneTypeId
     * @param twoTypeId
     * @return
     */
    @Override
    public List<TagsDRO> listBaseCodeMap(Integer plat, Integer oneTypeId, Integer twoTypeId, Integer threeTypeId) {
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(plat);
        tagsDIO.setOneTypeId(oneTypeId);
        tagsDIO.setTwoTypeId(twoTypeId);
        tagsDIO.setThreeTypeId(threeTypeId);
        tagsDIO.setStatus(GlobalConsts.YES);
        ResponseDTO<List<TagsDRO>> responseDTO = tagsListRemoteService.listByQuery(tagsDIO);
        log.info("获取公共配置入参：【{}】,出参：【{}】", JSON.toJSONString(tagsDIO), JSON.toJSONString(responseDTO));
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            return responseDTO.getData();
        }
        return Lists.newArrayList();
    }

    @Override
    public List<KVDict<Integer>> listInputRemark() {
        List<TagsDRO> tagList = listBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, OrderConsts.BASE_CODE_MAP_ONE_TYPE_COMMON_REMARK, null, null);
        
        if (CollectionUtil.isNullOrEmpty(tagList)) {
            return Lists.newArrayList();
        }

        return tagList.stream().map(tagsDRO -> KVDict.<Integer>builder().value(tagsDRO.getTwoTypeId()).text(tagsDRO.getName()).build()).collect(Collectors.toList());
    }

    @Override
    public boolean isOpenAdvanceQuote(AdvanceQuoteOpenQuery advanceQuoteOpenQuery) {
        if (Objects.isNull(advanceQuoteOpenQuery.getCityId())) {
            return false;
        }
        if (Objects.isNull(advanceQuoteOpenQuery.getServCategId())) {
            return false;
        }
        if (Objects.isNull(advanceQuoteOpenQuery.getProductId())) {
            return false;
        }

        // 城市试点
        TagsQuery tagsDIO = new TagsQuery();
        tagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        tagsDIO.setOneTypeId(OrderConsts.BASE_CODE_MAP_ONE_TYPE_ADVANCE_QUOTE_CITY);
        tagsDIO.setTwoTypeId(advanceQuoteOpenQuery.getCityId());
        tagsDIO.setStatus(GlobalConsts.YES);
        ResponseDTO<Integer> responseDTO = tagsListRemoteService.countByQuery(tagsDIO);
        if (NumberUtil.isNullOrZero(responseDTO.getData())) {
            return false;
        }

        // 分类开通全部， 三级分类是0
        TagsQuery servCategTagsDIO = new TagsQuery();
        servCategTagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        servCategTagsDIO.setOneTypeId(OrderConsts.BASE_CODE_MAP_ONE_TYPE_ADVANCE_QUOTE_PRODUCT_CATEG);
        servCategTagsDIO.setTwoTypeId(advanceQuoteOpenQuery.getServCategId());
        servCategTagsDIO.setThreeTypeId(GlobalConsts.YES);
        servCategTagsDIO.setStatus(GlobalConsts.YES);
        ResponseDTO<Integer> servCategTagsResponseDTO = tagsListRemoteService.countByQuery(servCategTagsDIO);
        if (NumberUtil.isNotNullOrZero(servCategTagsResponseDTO.getData())) {
            return true;
        }


        // 查询前台二级分类
        Integer productShowCategId = this.getProductShowCategId(advanceQuoteOpenQuery.getProductId(), advanceQuoteOpenQuery.getShowProductType());
        if (Objects.isNull(productShowCategId)) {
            return false;
        }

        // 分类开通全部， 三级分类是0
        TagsQuery categTagsDIO = new TagsQuery();
        categTagsDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        categTagsDIO.setOneTypeId(OrderConsts.BASE_CODE_MAP_ONE_TYPE_ADVANCE_QUOTE_PRODUCT_CATEG);
        categTagsDIO.setTwoTypeId(advanceQuoteOpenQuery.getServCategId());
        categTagsDIO.setThreeTypeId(productShowCategId);
        categTagsDIO.setStatus(GlobalConsts.YES);
        ResponseDTO<Integer> categTagsResponseDTO = tagsListRemoteService.countByQuery(categTagsDIO);
        if (NumberUtil.isNullOrZero(categTagsResponseDTO.getData())) {
            return false;
        }

        return true;
    }

    /**
     * 查询前台产品二级分类
     *
     * @param productId
     * @param showProductType
     * @return
     */
    private Integer getProductShowCategId(Integer productId, Integer showProductType) {
        // 没有前后台产品，或者是 前台产品直接查询
        if (Objects.isNull(showProductType) || Objects.equals(BaseProductConsts.EC_SHOW_TYPE, showProductType)) {
            // 查询产品前台二级分类
            ResponseDTO<List<ProductBaseDRO>> listResponseDTO = productForeignListRemoteService.listProductByProductIdList(Lists.newArrayList(productId));
            if (CollectionUtils.isEmpty(listResponseDTO.getData())) {
                return null;
            }
            ProductBaseDRO productBaseDRO = listResponseDTO.getData().get(0);
            if (Objects.equals(BaseProductConsts.EC_SHOW_TYPE, showProductType)) {
                return productBaseDRO.getCategId();
            }
        }

        // 通过后台产品查询前台产品
        DefaultEcProductQuery defaultEcProductQuery = new DefaultEcProductQuery();
        defaultEcProductQuery.setProductIdList(Lists.newArrayList(productId));
        defaultEcProductQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
        ResponseDTO<List<ProductBaseDRO>> showProductListResponseDTO = productForeignListRemoteService.listEcErpProductByQuery(defaultEcProductQuery);
        List<ProductBaseDRO> showProductList = showProductListResponseDTO.getData();
        if (CollectionUtil.isNullOrEmpty(showProductList)) {
            return null;
        }
        return showProductList.get(0).getCategId();
    }
}
